package nl.hanze.designpatterns.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;

import com.mysql.jdbc.Driver;

public class Executor {
	
	private static Executor instance;
	
	private static String host;
	private static String database;
	private static String username;
	private static String password;
	
	private Connection connection = null;
	private Statement statement = null;
	private PreparedStatement preparedStatement = null;
	private ResultSet resultSet = null;
	
	private Executor(String host, String database, String username, String password){
		this.host = host;
		this.database = database;
		this.username = username;
		this.password = password;
	}
	
	public void openConnection() throws SQLException{
		connection = DriverManager.getConnection(host + "/" + database, username, password);
	}
	
	public void closeConnection() throws SQLException{
		if(connection != null) connection.close();
		if(statement != null) statement.close();
		if(preparedStatement != null) preparedStatement.close();
		if(resultSet != null) resultSet.close();
	}
	
	public void executeQuery(String query) throws Exception {
	    statement = connection.createStatement();
	    if(query.startsWith("SELECT"))
	    	resultSet = statement.executeQuery(query);
	    else
	    	statement.executeUpdate(query);
	}
	
	public <T> Iterator<T> getIterator(String query, Class<T> c) throws Exception {
		this.executeQuery(query);
		return new RowIterator<T>(c, resultSet);
	}
	
	public static void init(String host, String database, String username, String password){
		try {
			if(Executor.instance != null)
				throw new Exception("Executor has already been initialized!");
			Class.forName("com.mysql.jdbc.Driver");
			instance = new Executor(host,database,username,password);
			System.out.println("[INFO] Database driver initialized succesful");
		} catch(ClassNotFoundException ex) {
		   System.out.println("Error: unable to load driver class!");
		   System.exit(1);
		} catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public static Executor getInstance() {
		return instance;
	}
}
